/*
 * ============================================================================
 *
 *       Filename:  QQWryLookup.h
 *
 *    Description:  
 *
 *         Author:  liangqing
 *
 * ============================================================================
 */
#ifndef QQWRYLOOKUP_H
#define QQWRYLOOKUP_H
#include "IPRecord.h"
#include <fstream>
using std::istream;
using std::ifstream;
using std::streambuf;
#include <iostream>

using namespace std;

class QQWryLookup {
  public:
    class iterator {

    };
    
    QQWryLookup(const char *filename);
    ~QQWryLookup(){
        _qqwry.close();
        //fclose(_qqwry);
        //if(_buf)
            //delete []_buf;
    }
    
    bool read_record(IPRecord *record);
    
    bool get(IPRecord *record);

    int read_all(); 
  
  protected:
    inline int _pos(char *offset, int size);

    inline bool _read(char *buf, int size) {
        //if(_rbuf_pos+size >= (int)sizeof(_rbuf)) {
            //int step_size = sizeof(_rbuf)-_rbuf_pos-1;
            //memcpy(buf, &_rbuf[_rbuf_pos], step_size);
            //_flush_rbuf();
            //memcpy(buf+step_size, &_rbuf[_rbuf_pos], size - step_size);
            //_rbuf_pos = size - step_size;
        //}
        //else {
            //memcpy(buf, &_rbuf[_rbuf_pos], size);
            //_rbuf_pos += size;
        //}
        //_sbuf->sgetn(buf, size);
        _qqwry.read(buf, size);
        return _qqwry.good();
        //fread(buf, size, 1, _qqwry);
        //return ferror(_qqwry)==0 && feof(_qqwry)==0;
    }

    inline bool _getn(char *buf, int size, char delim) {
        if(buf[0]=_peek())
            _qqwry.get(buf, size, delim);
        _getc();
        return _qqwry.good(); 
        //_read(buf, size);
        //while(*buf != delim) {
            //buf++;
            //size--;
        //}
        //*buf = '\0';
        //fseek(_qqwry, 1-size, SEEK_CUR);
        //_rbuf_pos = _rbuf_pos - size + 1;
        //char c;
        //int i=0;
        //size --;
        //while((c=(char)fgetc(_qqwry))!=delim && i<size){
                //buf[i]=c;
                //i++;
                //if(feof(_qqwry))
                    //return false;
        //}
        //buf[i]='\0';
        //return ferror(_qqwry)==0 && feof(_qqwry)==0;
    }

    inline char _peek() {
        return _sbuf->sgetc();
        //return _qqwry.peek();
        //char p = _getc();
        //fseek(_qqwry, -1, SEEK_CUR);
        //_rbuf_pos--;
        //return p;
    }

    inline char _getc() {
        return _sbuf->sbumpc();
        //return _qqwry.get();
        //return fgetc(_qqwry);
        //return _getc_rbuf();
    }
   
    //inline void _flush_rbuf() {
        //fread(_rbuf, sizeof(_rbuf), 1, _qqwry);
        //_rbuf_pos = 0;
        //_seek_pos += sizeof(_rbuf);
    //}

    //inline char _getc_rbuf() {
        //if(_rbuf_pos >= (int)sizeof(_rbuf))
            //_flush_rbuf();
        //return _rbuf[_rbuf_pos++];
    //}

    //inline bool _seek(int pos, int s=SEEK_SET) {
    inline bool _seek(int pos, std::ios::seekdir s=std::ios::beg) {
        _qqwry.seekg(pos, s);
        return _qqwry.good(); 
        //fseek(_qqwry, pos, s);
        //_seek_pos = ftell(_qqwry) - sizeof(_rbuf);
        //_flush_rbuf();
        //return ferror(_qqwry)==0 && feof(_qqwry)==0;
    }
    
    inline int _tell() {
        return _qqwry.tellg();
        //return ftell(_qqwry);
        //return _seek_pos + _rbuf_pos;
    }

    ifstream _qqwry;
    streambuf *_sbuf;
    //FILE *_qqwry;
    //char *_buf;
    //char _rbuf[1024];
    //int _rbuf_pos;
    //int _seek_pos;

    int _first_index;
    int _last_index;
    int _total;
};

#endif   /* #ifndef QQWRYLOOKUP_H */
